package org.ddd.orderdemo.domain.model.order;

import org.ddd.orderdemo.shared.exception.DemoBusinessException;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

public class Order {

    private Long id;

    private String orderNo;

    private Long totalPrice;

    private Integer status;

    public Order() {
    }

    public Order(Long id, Long totalPrice) {
        this.id = id;
        this.totalPrice = totalPrice;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public Long getTotalPrice() {
        return totalPrice;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public void setLockInventoryEndTime(Date lockEndTime) {

    }

    /*
    代码解释：
       在3.2.1一节中，我们讨论了聚合和聚合根的区别，聚合根也是DDD编程模型和传统编程模型之间的一个重要区别。
    在DDD中，模型不仅仅是数据的载体（即“贫血模型”），而是具有行为的实体（即“充血模型”）。通过聚合多个模型，
    聚合根能够实现复杂的业务逻辑，而不仅仅作为传输对象。（考虑到改造的复杂性，读者也可以选择不使使用充血模型，
    把业务逻辑交由领域服务来实现，也就是“DDD-Lite”）

       在传统的贫血模型中，我们习惯使用构造方法来完成对象的创建，但是构造方法不能有效的表达通用语言（new order
    和 create order的语义区别），所以我们这里使用聚合根来创建对象。其实复杂对象的创建最好是由工厂来实现，但是
    引入工厂的概念会带来额外的复杂性，为了简化框架，我们这里的做法是不再单独抽象工厂，而是让聚合根去承担了工厂的
    职责。这样做也是合理的，因为聚合根本身就承载了多个领域对象。

        我们在给对象赋值时，把操作委派给对象自身对应的setter方法，这样的好处就是保证了对象的自封装性。使创建对象
    这一操作更加安全。自封装性使验证变的更加简单，一次编写，随处可用（但要注意对象传输时的序列化时的问题，如setter
    对json的序列化的影响，这里也体现了领域对象不适合做传输对象的原因）。
    */
    /**
     * 创建订单
     *  @param  orderNo
     *  @param  deliveryAddress
     *  @param  orderItemList
     *  @param  userId
     *  @return
     */
    public  static Order create(String orderNo, DeliveryAddress deliveryAddress, List<OrderItem> orderItemList, Long userId) {
        Order  order  =  new  Order ();
        order.setOrderNo(orderNo);
        order.setDeliveryAddress(deliveryAddress);
        order.setOrderItemList(orderItemList);
        order.setUserId(userId);
        order.initialize();
        return order;
    }


    //订单状态初始化
    public void initialize() {
        this.setStatus(OrderStateEnum.INIT.getValue());
        this.setOrderTime(new Date());
        calculateTotalPrice();
    }

    private void calculateTotalPrice() {
    }



    public void setTotalPrice(Long totalPrice) {
        if (Objects.isNull(totalPrice) || totalPrice < 0)
            throw new DemoBusinessException("Illegal totalPrice");
        this.totalPrice = totalPrice;
    }

    public void setOrderNo(String orderNo) {
//        if (StringUtils.isBlank(orderNo))
        if (Objects.isNull(orderNo) || orderNo.isBlank())
            throw new DemoBusinessException("orderNo can not be null");
        this.orderNo = orderNo;
    }

    private void setDeliveryAddress(DeliveryAddress deliveryAddress) {
    }

    private void setUserId(Long userId) {
    }

    private void setOrderItemList(List<OrderItem> orderItemList) {
    }

    private void setOrderTime(Date date) {
    }

    private void setStatus(int value) {
    }

    public void setOrderId(Long id) {

    }

    public List<OrderItem> getOrderItemList() {
        return new ArrayList<>();
    }
}
